#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <iostream>
#include <vector>
#include <sstream>
#include <fstream>
#include <limits.h>
#include <sys/time.h>
#include "constants.h"

using namespace std;

typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;

ushort cksum(uchar* addr, int count) {
	/* Compute Internet Checksum for "count" bytes
	*         beginning at location "addr".
	*/
	register long sum = 0;
	ushort* shrt_addr = (ushort*)addr;
	while( count > 1 )  {
		/*  This is the inner loop */
	   sum += *shrt_addr++;
	   count -= 2;
	}
	

	/*  Add left-over byte, if any */
	if( count > 0 ){
		sum += *addr;
	}
	
	/*  Fold 32-bit sum to 16 bits */
	while (sum>>16)
		sum = (sum & 0xffff) + (sum >> 16);
	return ~sum;
}

ushort checkit(uchar* addr, int count){
	register long sum = cksum(addr, count);
	ushort* shrt_addr = (ushort*)addr;
	while( count > 1 )  {
		/*  This is the inner loop */
	   sum += *shrt_addr++;
	   count -= 2;
	}
	

	/*  Add left-over byte, if any */
	if( count > 0 ){
		sum += *addr;
	}
	
	/*  Fold 32-bit sum to 16 bits */
	while (sum>>16)
		sum = (sum & 0xffff) + (sum >> 16);
	return sum;
}

ushort cksum2(u_char *buf, int count){
	register ulong sum = 0;
	while( count > 1 )  {
		sum+= *buf++;
		count -= 2;
		if(sum & 0xFFFF0000){
			sum &= 0xFFFF;
			sum++;
		}
	}
	if( count > 0 )
	   sum += *buf;
	if(sum & 0xFFFF0000){
		sum &= 0xFFFF;
		sum++;
	}
	return ~(sum & 0xFFFF);
}

typedef struct {
	double startTime;
	int filePosition;
	uint sequenceNumber;
} packetInfo;


int main(int argc, char *argv[]) {
/*	uchar packet[10];
	packet[0] = 0x00;
	packet[1] = 0x00;
	packet[2] = 0xF7;
	packet[3] = 0xF6;
	packet[4] = 0xF5;
	packet[5] = 0xF4;
	packet[6] = 0x03;
	packet[7] = 0xF2;
	packet[8] = 0x00;
	packet[9] = 0x01;
	ushort sum = cksum(packet,10);
	ushort sum2 = cksum2(packet,10);
	printf("%X\n",0x210E);
	printf("Result from cksum1: %X\n",sum);
	printf("Result from cksum2: %X\n",sum2);
	printf("Checkit: %X\n",checkit(packet,10));
	*/
		/*
	struct timeval tv, tv2;
	struct timezone tz;
	gettimeofday(&tv, &tz);
	for(int i = 0; i<100000; i++){
		cout << "test" << endl;
	}
	gettimeofday(&tv2, &tz);
	double totSec= tv.tv_sec + (tv.tv_usec * .000001);
	double totSec2 = tv2.tv_sec + (tv2.tv_usec * .000001);
	cout << "Diff: " << (totSec2 - totSec) * 1000 << endl;

	double t = tv.tv_usec;
	double t2 = tv2.tv_usec;
	double m1 = t * .001;
	double m2 = t2 * .001;
	cout << "m1: " << m1 << endl;
	cout << "m2: " << m2 << endl;
	cout << "diff: " << m2 - m1 << endl;
	
	packetInfo window[5];
	for(int i = 0; i < 5; i++){
		window[i].sequenceNumber = (uint)i;
		gettimeofday(&tv,&tz);
		window[i].startTime = (tv.tv_usec * .001);
		window[i].filePosition = i * 2048;
	}
	
	for(int i = 0; i < 5; i++){
		cout << window[i].sequenceNumber << ": " << window[i].startTime << "ms at Position " << window[i].filePosition << endl;
	}
	
	cout << 5 % 2 << endl;
	*/
	
	cout << "BOF: " << SIG_BOF << endl;
    return 0;
}
